package com.esunny.resourcevisualization.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.esunny.resourcevisualization.domain.entity.User;
import com.esunny.resourcevisualization.domain.response.ReturnStructure;
import com.esunny.resourcevisualization.manage.UserManage;
import com.esunny.resourcevisualization.proxy.ZentaoSSOProxy;
import com.esunny.resourcevisualization.service.LoginService;
import com.esunny.resourcevisualization.util.ConstantUtil;
import com.esunny.resourcevisualization.util.JwtUtil;
import com.sun.istack.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * @version 1.0.0.0
 * @ClassName LoginServiceImpl
 * @Description 登录模块逻辑处理接口代码实现
 * @Author baochencong
 * @Date 2020/10/9 17:03
 */
@Service
public class LoginServiceImpl implements LoginService {

    private String username = "username";

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Resource
    private UserManage userManage;

    @Resource
    private HttpServletResponse response;

    private static final Logger LOGGER = LoggerFactory.getLogger(LoginServiceImpl.class);

    @Override
    public ReturnStructure login(String username, String password) {
        User userInfo = userManage.getUserByName(username);
        if (userInfo != null){
            if (userInfo.getPassword().equals(password)){
                String ticket = SetResponseAndGetTicket(userInfo);
                Map<String, Object> loginMap = new HashMap<>(3);
                loginMap.put("message", "登录成功");
                loginMap.put("ticket", ticket);
                loginMap.put("user", userInfo);
                return ReturnStructure.SUCCESS("登陆成功",loginMap);
            }
            return ReturnStructure.ERROR("用户名或密码错误",null);
        }
        return ReturnStructure.ERROR("该用户不存在",null);
}
    @Override
    public void updateUserInfo(Map<String, String> loginInfo) {
        User userInfo = getUserInfo(loginInfo);
        if (userInfo == null) {
            return;
        }
        if (!userIsExisted(loginInfo.get(username))) {
            userManage.addUser(userInfo);
        }
    }

    /**
     * 获取用户详细信息
     *
     * @param loginInfo 用户信息
     * @return 用户详细信息
     */
    private User getUserInfo(Map<String, String> loginInfo) {
        JSONObject userDetailInfo = ZentaoSSOProxy.post("/auth/detail", loginInfo);
        User user = new User();
        user.setUsername(loginInfo.get(username));
        boolean noGroupInfo = userDetailInfo.getJSONObject("data").getString("group").equals("false");
        if (noGroupInfo) {
            return null;
        }
        user.setRealName(userDetailInfo.getJSONObject("data").getJSONObject("user").getString("realname"));
        user.setUserGroupId(userDetailInfo.getJSONObject("data").getJSONObject("group").getIntValue("id"));
        user.setUserGroupName(userDetailInfo.getJSONObject("data").getJSONObject("group").getString("name"));
        // 获取right结点
        JSONObject rightNode = userDetailInfo.getJSONObject("data").getJSONObject("right");
        user.setUserLevel(isAdmin(rightNode) ? 1 : 0);
        return user;
    }

    /**
     * 获取ticket并设置响应头
     *
     * @param user 用户信息
     * @return ticket
     */
    private String SetResponseAndGetTicket(User user) {
        String ticket = JwtUtil.createJwt(user);
        Cookie cookie = new Cookie("ticket", ticket);
        cookie.setPath(contextPath);
        cookie.setMaxAge(ConstantUtil.JWT_EXPIRE_SECOND);
        response.setHeader("ticket", ticket);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.addCookie(cookie);
        return ticket;
    }

    /**
     * 判断用户是否为管理员
     *
     * @param rightNode 权限节点
     * @return 用户是否是管理员
     */
    private boolean isAdmin(@NotNull JSONObject rightNode) {
        // 判断是否有study节点数据段
        // TODO study节点需要改成resourcevisualization
        boolean hasStudyNode = rightNode.containsKey("study");
        if (hasStudyNode) {
            Boolean isAdmin = rightNode.getJSONObject("study").getBoolean("admin");
            if (isAdmin != null) {
                return isAdmin;
            }
        }
        return false;
    }

    /**
     * 通过代理获取用户登录状态
     *
     * @param loginInfo 用户名和密码
     * @return 是否登录成功
     */
    private boolean loginStatus(Map<String, String> loginInfo) {
        JSONObject postInfo = ZentaoSSOProxy.post("/auth/login", loginInfo);
        Map<String, String> returnInfo = JSONObject.parseObject(postInfo.toJSONString(), new TypeReference<Map<String, String>>() {
        });
        LOGGER.info("returnInfo:{}", returnInfo);
        return returnInfo.get("code").equals("200");
    }

    /**
     * 通过用户名判断用户是否存在
     *
     * @param username 用户名
     * @return 用户是否存在
     */
    private boolean userIsExisted(String username) {
        return userManage.getUserByName(username) != null;
    }
}
